<template>
  <div id="cesiumContainer"></div>
  <div id="menu">
    <select id="dropDown" ref="dropDownDom" @change="edit">
      <option value="0">Color By Building Material</option>
      <option value="1">Color By Distance To Selected Location</option>
      <option value="2">Highlight Residential Buildings</option>
      <option value="3">Show Office Buildings Only</option>
      <option value="4">Show Apartment Buildings Only</option>
    </select>
    <table class="infoPanel">
      <tbody>
      <tr>
        <td>Click on a building to select as the central location</td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup>
import * as Cesium from 'cesium';
import {onMounted} from "vue";
import * as Ceisum from "cesium";


let viewer = null;
let handler = null;
let osmBuildingsTileset = null;

onMounted(async () => {
  await init();
  await loadOsmBuildingsTiles();
  await colorByMaterial();
})
const init = async () => {
  Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NTI3OGI2Ni05YmJhLTRlMTYtYjdiNC1hM2E5ZjI1MGYxZmIiLCJpZCI6MTQ0NTcxLCJpYXQiOjE3MDMxNTQ2MzZ9.-ab5sCTIXoyCUMMGv35NQBbR0h7pxsxu78D3AfCVTek'
  const customImageryProvider = new Cesium.ArcGisMapServerImageryProvider({
    url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
  })
  const mapboxImageryProvider = new Cesium.UrlTemplateImageryProvider({
    url: 'https://a.tiles.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94ZGV2dXNlcjUyMCIsImEiOiJjbHFrb2w3M2IyNHB2MnFtZWx1ZzFjNHZmIn0.CMoLsalSeXlJiLBNyUK1nA'
  })
  var url = 'http://localhost:8081/geoserver/nurc/wms'; //Geoserver URL
  // Cesium之Viewer初始常用配置
  viewer = new Cesium.Viewer('cesiumContainer', {
    shadows: false, // 阴影
    animation: false, // 左下角控制动画
    baseLayerPicker: false, // 右上角图层选择器
    fullscreenButton: false, // 全屏
    geocoder: false, // 右上角搜素
    homeButton: false, // 主页
    infoBox: false, // 信息框
    scene3DOnly: true, // 仅仅显示3D，可以隐藏右上角2D和3D按钮
    selectionIndicator: false, // 绿色选择框
    timeline: false, // 最下面时间轴
    navigationHelpButton: true, // 右上角帮助按钮
    navigationInstructionsInitiallyVisible: true, // 导航指令
    useDefaultRenderLoop: true,
    showRenderLoopErrors: true,
    projectionPicker: false, // 投影选择器
    terrainProvider: await Cesium.createWorldTerrainAsync(), // 地形
    // imageryProvider:  wmsImageryProvider // 影像图
  });
  viewer.scene.globe.depthTestAgainstTerrain = true; // 开启地形深度检测
  // 取消双击时间
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  viewer._cesiumWidget._creditContainer.style.display = "none"; // 隐藏cesium icon
  // document.querySelector('.cesium-infoBox-camera').style.display = 'none';//隐藏infobox camera
  // 加载离线地图服务 - web服务影像提供器来实例化影像图层
  const imageryLayers = viewer.imageryLayers;
  const scene = viewer.scene;
  // imageryLayers.addImageryProvider(provider);
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
}

const loadOsmBuildingsTiles = async () => {
  // Add cesium OSM buildings to the scene as 3D Tileset
  osmBuildingsTileset = await Cesium.createOsmBuildingsAsync();
  console.log('output-> osmBuildingsTileset::: ', osmBuildingsTileset)
  viewer.scene.primitives.add(osmBuildingsTileset);

  // Set the initial camera to look at Seattle
  viewer.scene.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370),
    orientation: {
      heading: Cesium.Math.toRadians(10),
      pitch: Cesium.Math.toRadians(-10),
    }
  });
}

// Styling functions
// Color by material checks for null values since not all
// buildings have the material property.
function colorByMaterial() {
  osmBuildingsTileset.style = new Cesium.Cesium3DTileset({
    defines: {
      material: "${features['building:material']}"
    },
    color: {
      conditions: [
        ["${material} === null", "color('white')"],
        ["${material} === 'glass'", "color('skyblue', 0.5)"],
        ["${material} === 'concrete'", "color('grey')"],
        ["${material} === 'brick'", "color('indianred')"],
        ["${material} === 'stone'", "color('lightslategrey')"],
        ["${material} === 'metal'", "color('lightgrey')"],
        ["${material} === 'steel'", "color('lightsteelblue')"],
        ["true", "color('white')"], // This is the else case
      ]
    }
  })
}

// 高亮所有住宅区
function highlightAllResidentialBuildings() {
  osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        [
          "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'",
          "color('cyan', 0.9)",
        ],
        [
          true,
          "color('white')"
        ]
      ]
    }
  })
}

// 展示建筑物类型
function showByBuildingType(buildingType) {
  switch (buildingType) {
    case "office":
      osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
        show: "${feature['building']} === 'office'",
      });
      break;
    case "apartments":
      osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
        show: "${feature['building']} === 'apartments'",
      });
      break;
    default:
      break;
  }
}

// Color the buildings based on their distance from a selected central location
function colorByDistanceToCoordinate(pickedLatitude, pickedLongitude) {
  osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({
    defines: {
      distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`,
    },
    color: {
      conditions: [
        ["${distance} > 0.014", "color('blue')"],
        ["${distance} > 0.010", "color('green')"],
        ["${distance} > 0.006", "color('yellow')"],
        ["${distance} > 0.0001", "color('red')"],
        ["true", "color('white')"]
      ]
    }
  })
}

// When dropdown option is not "Color By Distance To Selected Location"
// remove the left click input event for selecting a central location
function removeCoordinatePickingOnLeftClick() {
  document.querySelector(".infoPanel").style.visibility = "hidden";
  handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}

const edit = () => {
  let dropDownDomTemp = document.getElementById('dropDown')
  console.log('dropDownDomTemp.value::: ', dropDownDomTemp.value)
  switch (dropDownDomTemp.value) {
    case "0":
      removeCoordinatePickingOnLeftClick();
      colorByMaterial();
      break;
    case "1":
      // Default to Space Needle as the central location
      colorByDistanceToCoordinate(47.62051, -122.34931);
      document.querySelector(".infoPanel").style.visibility = "visible";
      // Add left click input to select a building to and extract its coordinates
      handler.setInputAction(function (movement) {
        console.log('output-> movement', movement)
        console.log('output-> movement.position', movement.position)
        viewer.selectedEntity = undefined;
        const pickedBuilding = viewer.scene.pick(movement.position)
        console.log('output-> pickedBuilding::: ', pickedBuilding)
        if(pickedBuilding) {
          const pickedLatitude = pickedBuilding.getProperty(
            "cesium#latitude"
          );
          const pickedLongitude = pickedBuilding.getProperty(
            "cesium#longitude"
          );
          colorByDistanceToCoordinate(pickedLatitude, pickedLongitude)
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      break;
    case "2":
      removeCoordinatePickingOnLeftClick();
      highlightAllResidentialBuildings();
      break;
    case "3":
      removeCoordinatePickingOnLeftClick();
      showByBuildingType("office")
      break;
    case "4":
      removeCoordinatePickingOnLeftClick();
      showByBuildingType("apartment")
      break;
    default:
      break;
  }

}


</script>


<style>
html,
body,
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

#menu {
  z-index: 999;
  position: absolute;
  top: 20px;
  left: 20px;
}

.toolbar {
  position: absolute;
  top: 10px;
  left: 20px;
  background-color: rgb(0, 0, 0, 0);
}
</style>
